﻿//-----------------------------------------------------------------------
// <copyright file="ToolPartUserControl.cs" company="Microsoft 
// Corporation">
// Copyright (c) Microsoft Corporation.
// All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Anil Dwarakanath</author>
// <email>anildwa@microsoft.com</email>
// <date>31-Dec-2010</date>
// <summary>Main Class for Rendering ToolPart UserControl</summary>
//-----------------------------------------------------------------------
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ContentAggregationWebPart
{
    public partial class ToolPartUserControl : UserControl
    {
        private ContentAggregationWebPart SelectedWebPart;

        #region Constructors
        public ToolPartUserControl() { }


        public ToolPartUserControl(WebPart ToolPaneWebPart)
        {
            this.SelectedWebPart = (ContentAggregationWebPart)ToolPaneWebPart;

            if (this.SelectedWebPart.SiteCollectionUrl == null || this.SelectedWebPart.ViewFields == null)
                return;


            this.SiteCollectionUrl.Text = SelectedWebPart.SiteCollectionUrl;
            this.txtCamlQuery.Text = SelectedWebPart.CamlQuery;
            PopulateToolPartFilters();
            //PopulateWebPartDisplayColumns();


            PopulateToolPartGroupbyFields();


            ShowExtendedDisplayColumns();

            SetExtendedDisplayColumnControls();
            SetCAMLQuery();


        }


        #endregion

        #region UserControl Events
        protected void Page_Load(object sender, EventArgs e)
        {
            this.SelectedWebPart.SiteCollectionUrl = this.SiteCollectionUrl.Text;
            if (this.txtCamlQuery.Text != "")
                this.SelectedWebPart.CamlQuery = this.txtCamlQuery.Text;

            btnGetSites.Click += new EventHandler(btnGetSites_Click);
            btnGetContentTypes.Click += new EventHandler(btnGetContentTypes_Click);
            btnGetFields.Click += new EventHandler(btnGetFields_Click);
            btnCamlQuery.Click += new EventHandler(btnCamlQuery_Click);
        }


        private void btnCamlQuery_Click(object sender, EventArgs e)
        {
            txtCamlQuery.Text = GetCamlQuery();
        }



        private void btnGetFields_Click(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                SPFields.Items.Clear();
                GetAvailableFields();

                SPBuiltInFields.Items.Clear();
                GetBuiltInFields();

                divSPFields.Style["display"] = "block";
                divSPBuiltInFields.Style["display"] = "block";

            }

        }

        private void btnGetContentTypes_Click(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                SPContentTypes.Items.Clear();
                GetAvailableContentTypes();
                divSPContentTypes.Style["display"] = "block";
            }

        }


        private void btnGetSites_Click(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                SPSites.Items.Clear();
                GetSubSites();
                divSPSites.Style["display"] = "block";

            }

        }
        #endregion



        #region PrivateMethods



        /// <summary>
        /// Shows available fields that can be selected to show on SPGridView
        /// </summary>
        private void ShowExtendedDisplayColumns()
        {

                List<BaseSPType> displayfields = new List<BaseSPType>();

                foreach (string item in this.SelectedWebPart.ViewFields)
                {
                    displayfields.Add((BaseSPType)item.ToUserDefinedType<BaseSPType>());

                }


                rpDisplayColumns.DataSource = displayfields;
                rpDisplayColumns.DataBind();


                
        }


        /// <summary>
        /// Renders the state of the controls based on persisted webpart properties
        /// </summary>
        private void SetExtendedDisplayColumnControls()
        {
            foreach (string item in this.SelectedWebPart.ExtendedDisplayColumns)
            {

                ExtendedDisplayColumnType excol = (ExtendedDisplayColumnType)item.ToUserDefinedType<ExtendedDisplayColumnType>();

                foreach (RepeaterItem rpItem in rpDisplayColumns.Items)
                {
                    if (excol.Title == ((CheckBox)rpItem.Controls[1]).Text && excol.Name == ((HiddenField)rpItem.Controls[3]).Value)
                    {
                        ((CheckBox)rpItem.Controls[1]).Checked = true;


                        if (excol.IsHyperLink == true)
                        {
                            ((CheckBox)rpItem.Controls[5]).Checked = true;
                        }

                        if (excol.LinkUrl != "" && excol.LinkUrl == "FileRef")
                        {
                            ((CheckBox)rpItem.Controls[7]).Checked = true;
                        }

                        if (excol.LinkUrl != "" && excol.LinkUrl != "FileRef")
                        {
                            ((TextBox)rpItem.Controls[9]).Text = excol.LinkUrl;
                        }

                        if (excol.IsVisible == true)
                        {
                            ((CheckBox)rpItem.Controls[11]).Checked = true;
                        }

                        if (excol.IsClickToExpand == true)
                        {
                            ((CheckBox)rpItem.Controls[13]).Checked = true;
                        }
                    }
                }
            }

        }


        /// <summary>
        /// Get the previously stored property value for the site collection
        /// </summary>
        private void SetCAMLQuery()
        {

            txtCamlQuery.Text = this.SelectedWebPart.CamlQuery;

        }


        /// <summary>
        /// Is Invoked when the "Apply" button is clicked on the Tool Part window
        /// </summary>
        public void ApplyToolPartChanges(WebPart ToolPaneWebPart)
        {
            SelectedWebPart.SiteCollectionUrl = SiteCollectionUrl.Text;
            SelectedWebPart.CamlQuery = txtCamlQuery.Text;


            if (SelectedWebPart.SiteCollectionUrl == "")
                return;


            if (SelectedWebPart.ViewFields == null)
                SelectedWebPart.ViewFields = new List<string>();

            //if (SelectedWebPart.DisplayColumns == null)
            //    SelectedWebPart.DisplayColumns = new List<string>();


            if (SelectedWebPart.Webs == null)
                SelectedWebPart.Webs = new List<string>();


            if (SelectedWebPart.ExtendedDisplayColumns == null)
                SelectedWebPart.ExtendedDisplayColumns = new List<string>();


            if (SelectedWebPart.GroupBy == null)
                SelectedWebPart.GroupBy = "";


            if (SelectedWebPart.PageSize == null)
                SelectedWebPart.PageSize = "";

           
            SetSelectedWebs(SelectedWebPart.Webs);


            SetWebPartFields(SelectedWebPart.ViewFields);
            SetBuiltInFields(SelectedWebPart.ViewFields);
            PopulateToolPartFilters();
            //PopulateToolPartGroupbyFields();


            //SetWebPartDisplayColumns(SelectedWebPart.DisplayColumns);

            if (GroupbyFields.SelectedItem != null)
                this.SelectedWebPart.GroupBy = GroupbyFields.SelectedItem.Value;


            SelectedWebPart.PageSize = txtPageSize.Text;

            SetExtendedDisplayColumns(SelectedWebPart.ExtendedDisplayColumns);

        

            


        }


        /// <summary>
        /// Shows the available fields in the Group By Dropdown list box
        /// </summary>
        private void PopulateToolPartGroupbyFields()
        {
            GroupbyFields.Items.Clear();
            GroupbyFields.Items.Add(new ListItem("", ""));

            foreach (string item in SelectedWebPart.ExtendedDisplayColumns)
            {
                GroupbyFields.Items.Add(new ListItem(((ExtendedDisplayColumnType)item.ToUserDefinedType<ExtendedDisplayColumnType>()).Title,
                    ((ExtendedDisplayColumnType)item.ToUserDefinedType<ExtendedDisplayColumnType>()).Name));
            }


            foreach (ListItem item in GroupbyFields.Items)
            {
                if (item.Value == this.SelectedWebPart.GroupBy)
                {
                    item.Selected = true;
                }
            }


            txtPageSize.Text = SelectedWebPart.PageSize;
        }




        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        /// <param name="ExtendedDisplayColumns">WebPart Property persisting the display columns</param>
        private void SetExtendedDisplayColumns(List<string> ExtendedDisplayColumns)
        {

            ExtendedDisplayColumns.Clear();
            GroupbyFields.Items.Clear();

            GroupbyFields.Items.Add(new ListItem("", ""));


            foreach (RepeaterItem item in rpDisplayColumns.Items)
            {
                if (((CheckBox)item.Controls[1]).Checked)
                {
                    ExtendedDisplayColumnType excol = new ExtendedDisplayColumnType();
                    excol.Title =((CheckBox)item.Controls[1]).Text;
                    excol.Name = ((HiddenField)item.Controls[3]).Value;


                    if (((CheckBox)item.Controls[5]).Checked)
                    {
                        excol.IsHyperLink = true;

                        if (((CheckBox)item.Controls[7]).Checked)
                        {
                            excol.LinkUrl = "FileRef";
                        }
                        else
                        {
                            excol.LinkUrl = ((TextBox)item.Controls[9]).Text;
                        }
                    }

                    excol.IsVisible = ((CheckBox)item.Controls[11]).Checked;
                    excol.IsClickToExpand = ((CheckBox)item.Controls[13]).Checked;

                    ExtendedDisplayColumns.Add(excol.ToString<ExtendedDisplayColumnType>());
                    GroupbyFields.Items.Add(new ListItem(excol.Title,excol.Name));
                }
            }

            foreach (ListItem item in GroupbyFields.Items)
            {
                if (item.Value == this.SelectedWebPart.GroupBy)
                {
                    item.Selected = true;
                }
            }
        }


        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        /// <param name="SelectedWebs">WebPart Property persisting the selected webs</param>
        private void SetSelectedWebs(List<string> SelectedWebs)
        {
            SelectedWebs.Clear();


            foreach (ListItem siteItem in SPSites.Items)
            {
                if (siteItem.Selected)
                {
                    BaseSPType web = new BaseSPType
                    {
                        Guid = siteItem.Value,
                        Title = siteItem.Text,

                    };

                    SelectedWebPart.Webs.Add(web.ToString<BaseSPType>());
                }
            }
        }


        /// <summary>
        /// Renders the filters DDLB
        /// </summary>
        private void PopulateToolPartFilters()
        {
            FilterFields.Items.Clear();
            foreach (string item in SelectedWebPart.ViewFields)
            {
                FilterFields.Items.Add(new ListItem(((BaseSPType)item.ToUserDefinedType<BaseSPType>()).Name,
                    ((BaseSPType)item.ToUserDefinedType<BaseSPType>()).Type));
            }
        }

        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        public void GetSubSites()
        {
            using (SPSite siteCollection = new SPSite(SelectedWebPart.SiteCollectionUrl))
            {
                foreach (SPWeb web in siteCollection.AllWebs)
                {
                    SPSites.Items.Add(new ListItem(web.Title,web.ID.ToString()));

                }
            }

            SPSites.Items.Sort();


        }

        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        public void GetAvailableContentTypes()
        {
         

            using (SPSite siteCollection = new SPSite(SelectedWebPart.SiteCollectionUrl))
            {
                foreach (ListItem item in SPSites.Items)
                {
                    if (item.Selected)
                    {
                       
                        foreach (SPContentType ct in siteCollection.AllWebs[new Guid(item.Value)].ContentTypes)
                        {
                            SPContentTypes.Items.Add(new ListItem(ct.Name,ct.Id.ToString()));
                        }
                    }

                }
            }

            SPContentTypes.Items.Sort();

        }


        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        public void GetAvailableFields()
        {
            using (SPSite siteCollection = new SPSite(SelectedWebPart.SiteCollectionUrl))
            {
                foreach (ListItem siteItem in SPSites.Items)
                {
                    if (siteItem.Selected)
                    {

                        foreach(ListItem contenttypeItem in SPContentTypes.Items)
                        {
                            if (contenttypeItem.Selected)
                            {
                                if (HasContentType(contenttypeItem.Text, siteCollection.AllWebs[new Guid(siteItem.Value)]))
                                {
                                    foreach (SPField field in siteCollection.AllWebs[new Guid(siteItem.Value)].ContentTypes[contenttypeItem.Text].Fields)
                                    {
                                        SPFields.Items.Add(new ListItem(field.Title + string.Format("[{0}]", contenttypeItem.Text),
                                        field.Id.ToString()));
                                       
                                    }
                                }
                            }
                        }
                      
                    }

                }
            }

            SPFields.Items.Sort();


        }


        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        private void GetBuiltInFields()
        {
            using (SPSite siteCollection = new SPSite(SelectedWebPart.SiteCollectionUrl))
            {

                foreach (ListItem spsiteItem in SPSites.Items)
                {
                    if (spsiteItem.Selected)
                    {
                        foreach (SPField siteField in siteCollection.RootWeb.Fields)
                        {
                            if (SPBuiltInFieldId.Contains(siteField.Id))
                            {
                                if (!SPBuiltInFields.Items.Contains(new ListItem(siteField.InternalName, siteField.Id.ToString())))
                                {
                                    SPBuiltInFields.Items.Add(new ListItem(siteField.InternalName, siteField.Id.ToString()));
                                    
                                }

                            }

                        }
                    }
                }

            }

            SPBuiltInFields.Items.Sort();
        }


        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        public void SetWebPartFields(List<string> ViewFields)
        {
            using (SPSite siteCollection = new SPSite(SelectedWebPart.SiteCollectionUrl))
            {
                foreach (ListItem spsiteItem in SPSites.Items)
                {
                    if (spsiteItem.Selected)
                    {
                        SelectedWebPart.ViewFields.Clear();
                     
                        foreach (ListItem spcontenttypeItem in SPContentTypes.Items)
                        {
                            if (spcontenttypeItem.Selected)
                            {
                                if (HasContentType(spcontenttypeItem.Text, siteCollection.AllWebs[new Guid(spsiteItem.Value)]))
                                {
                                    
                                    foreach (SPField field in siteCollection.AllWebs[new Guid(spsiteItem.Value)].ContentTypes[spcontenttypeItem.Text].Fields)
                                    {
                                        foreach (ListItem fieldItem in SPFields.Items)
                                        {
                                            if (fieldItem.Selected && fieldItem.Value == field.Id.ToString())
                                            {
                                                BaseSPType customField = new BaseSPType
                                                {
                                                    Guid = field.Id.ToString(),
                                                    Title = field.Title,
                                                    Type = field.Type.ToString() ,
                                                    Name = field.InternalName
                                                };
                                                ViewFields.Add(customField.ToString<BaseSPType>());
                                               
                                                 
                                            }
                                        }


                                      
                                    }
                                }
                            }
                        }

                    }

                }
            }

            

        }


        /// <summary>
        /// Persists the selected control values into the webpart properties
        /// </summary>
        public void SetBuiltInFields(List<string> ViewFields)
        {
            using (SPSite siteCollection = new SPSite(SelectedWebPart.SiteCollectionUrl))
            {
                foreach (ListItem spsiteItem in SPSites.Items)
                {
                    if (spsiteItem.Selected)
                    {
                        foreach (SPField field in siteCollection.RootWeb.Fields)
                        {
                            foreach (ListItem builtinField in SPBuiltInFields.Items)
                            {
                                if (builtinField.Selected && builtinField.Value == field.Id.ToString())
                                {
                                    BaseSPType customField = new BaseSPType
                                    {
                                        Guid = field.Id.ToString(),
                                        Title = field.Title,
                                        Type = field.Type.ToString() ,
                                        Name = field.InternalName
                                    };
                                    ViewFields.Add(customField.ToString<BaseSPType>());
                                  
                                }
                            }
                        }
                    }
                }
                
            }
        }

        /// <summary>
        /// Checks if the content type exists in the selected web
        /// </summary>
        private bool HasContentType(string ContentTypeName, SPWeb web)
        {
            if (web.ContentTypes[ContentTypeName] != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        /// <summary>
        /// Builds the CAML query based on the selected criteria
        /// </summary>
        private string GetCamlQuery()
        {

            XElement xWhere = new XElement("Where");
            if (txtCamlQuery.Text == "")
            {


                XElement xCondition = new XElement(Conditions.SelectedItem.Value);
                XElement xFieldRef = new XElement("FieldRef", new XAttribute("Name", FilterFields.SelectedItem.Text));
                XElement xValue = new XElement("Value", new XAttribute("Type", FilterFields.SelectedItem.Value));
                xValue.Value = txtValue.Text;

                xCondition.Add(xFieldRef);

                if (!Conditions.SelectedItem.Value.Contains("Null"))
                    xCondition.Add(xValue);
                
                xWhere.Add(xCondition);
            }
            else
            {
                if (Filter.SelectedItem.Value != "Filter")
                {
                    xWhere = XElement.Parse(Server.HtmlDecode(txtCamlQuery.Text));

                    XElement xFilter = new XElement(Filter.SelectedItem.Value);
                    XElement xCondition = new XElement(Conditions.SelectedItem.Value);
                    XElement xFieldRef = new XElement("FieldRef", new XAttribute("Name", FilterFields.SelectedItem.Text));
                    XElement xValue = new XElement("Value", new XAttribute("Type", FilterFields.SelectedItem.Value));
                    xValue.Value = txtValue.Text;

                    xCondition.Add(xFieldRef);


                    if (!Conditions.SelectedItem.Value.Contains("Null"))
                        xCondition.Add(xValue);

                    xWhere.Add(xCondition);


                    xFilter.Add(xWhere.Elements());
                    xWhere.Elements().Remove();
                    xWhere.Add(xFilter);

                }

            }
         
            return xWhere.ToString();
        }

        #endregion
    }
}
